package com.kaizeli.website.service.impl;

import com.kaizeli.website.pojo.dto.ChangePasswordDTO;
import com.kaizeli.website.pojo.dto.UserLoginDTO;
import com.kaizeli.website.pojo.dto.UserRegisterDTO;
import com.kaizeli.website.service.UserService;
import com.kaizeli.website.util.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    /**
     * 创建用户（管理员专用）
     * 权限说明：
     * - 总管理员(2)：可以创建管理员(1)和子管理员(0)
     * - 管理员(1)：只能创建子管理员(0)
     * - 子管理员(0)：无创建权限
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> createUser(UserRegisterDTO dto, String currentUsername) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 检查当前用户权限级别
            if (currentUsername == null || currentUsername.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "未登录或登录已过期");
                return result;
            }
            
            String checkAdminSql = "SELECT administrator FROM users WHERE username = ?";
            Integer currentUserLevel = jdbcTemplate.queryForObject(checkAdminSql, Integer.class, currentUsername);
            
            // 子管理员(0)无创建权限
            if (currentUserLevel == null || currentUserLevel == 0) {
                result.put("success", false);
                result.put("message", "权限不足：只有管理员及以上级别可以创建用户");
                log.warn("用户 {} 尝试创建用户但权限不足（级别：{}）", currentUsername, currentUserLevel);
                return result;
            }

            // 2. 判断要创建的用户类型
            Integer creatingUserLevel = dto.getAdministrator(); // 0=子管理员, 1=管理员, 2=总管理员
            if (creatingUserLevel == null) {
                creatingUserLevel = 0; // 默认创建子管理员
            }
            
            // 3. 权限检查：管理员(1)只能创建子管理员(0)
            if (currentUserLevel == 1 && creatingUserLevel >= 1) {
                result.put("success", false);
                result.put("message", "权限不足：管理员只能创建子管理员");
                log.warn("管理员 {} 尝试创建管理员级别用户，操作被拒绝", currentUsername);
                return result;
            }
            
            // 4. 只有总管理员(2)可以创建管理员(1)
            if (creatingUserLevel == 1 && currentUserLevel != 2) {
                result.put("success", false);
                result.put("message", "权限不足：只有总管理员可以创建管理员");
                log.warn("用户 {} 尝试创建管理员，但不是总管理员", currentUsername);
                return result;
            }
            
            // 5. 禁止创建总管理员
            if (creatingUserLevel >= 2) {
                result.put("success", false);
                result.put("message", "禁止创建总管理员账号");
                log.warn("用户 {} 尝试创建总管理员账号，操作被拒绝", currentUsername);
                return result;
            }

            String username = dto.getUsername();
            String password = dto.getPassword();
            Long employeeId = dto.getEmployeeId();
            
            // 检查是否绑定员工
            boolean bindEmployee = (employeeId != null && employeeId > 0);
            
            if (bindEmployee) {
                // 选择绑定员工：只记录employee_id，用户名和密码由用户手动输入
                // 检查员工是否存在
                String checkEmployeeSql = "SELECT id, name FROM employee WHERE id = ?";
                Map<String, Object> employee;
                try {
                    employee = jdbcTemplate.queryForMap(checkEmployeeSql, employeeId);
                } catch (Exception e) {
                    result.put("success", false);
                    result.put("message", "选择的员工不存在");
                    return result;
                }
                
                // 检查该员工是否已被绑定
                String checkBindingSql = "SELECT COUNT(*) FROM users WHERE employee_id = ?";
                Integer bindCount = jdbcTemplate.queryForObject(checkBindingSql, Integer.class, employeeId);
                if (bindCount != null && bindCount > 0) {
                    result.put("success", false);
                    result.put("message", "该员工已被绑定到其他用户");
                    return result;
                }
                
                log.info("创建{}，绑定员工，员工ID：{}", creatingUserLevel == 1 ? "管理员" : "子管理员", employeeId);
            }
            
            // 用户名和密码验证（无论是否绑定员工，都需要手动输入）
            if (username == null || username.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "请提供用户名");
                return result;
            }
            
            if (password == null || password.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "请提供密码");
                return result;
            }
            
            // 用户名验证
            if (!username.matches("^[a-zA-Z0-9_]{3,50}$")) {
                result.put("success", false);
                result.put("message", "用户名只能包含字母、数字和下划线，长度3-50位");
                return result;
            }
            
            String userTypeName = creatingUserLevel == 1 ? "管理员" : "子管理员";
            if (bindEmployee) {
                log.info("创建{}，绑定员工，用户名：{}", userTypeName, username);
            } else {
                log.info("创建{}，不绑定员工，用户名：{}", userTypeName, username);
            }

            // 3. 检查用户名是否已存在
            String checkUserSql = "SELECT COUNT(*) FROM users WHERE username = ?";
            Integer count = jdbcTemplate.queryForObject(checkUserSql, Integer.class, username);
            if (count != null && count > 0) {
                result.put("success", false);
                result.put("message", "用户名已存在");
                return result;
            }

            // 4. 密码校验
            if (password.length() < 6 || password.length() > 100) {
                result.put("success", false);
                result.put("message", "密码长度必须在6-100位之间");
                return result;
            }

            // 5. 🔐 BCrypt加密密码
            String encryptedPassword = passwordEncoder.encode(password);
            log.info("用户 {} 的密码已加密", username);

            // 6. 插入数据库
            String insertSql = "INSERT INTO users (username, password, administrator, email, phone, employee_id, login_count) VALUES (?, ?, ?, ?, ?, ?, 0)";
            jdbcTemplate.update(
                insertSql,
                username,
                encryptedPassword,
                creatingUserLevel,
                dto.getEmail(),
                dto.getPhone(),
                bindEmployee ? employeeId : null
            );

            // 7. 获取新创建用户的ID
            String getIdSql = "SELECT id FROM users WHERE username = ?";
            Long userId = jdbcTemplate.queryForObject(getIdSql, Long.class, username);

            result.put("success", true);
            result.put("message", "用户创建成功");
            result.put("userId", userId);
            result.put("username", username);
            result.put("userLevel", creatingUserLevel);
            
            log.info("用户创建成功：ID={}, 用户名={}, 类型={}, 权限级别={}, 绑定员工={}", 
                userId, username, userTypeName, creatingUserLevel, bindEmployee);

        } catch (Exception e) {
            log.error("创建用户失败：{}", e.getMessage(), e);
            result.put("success", false);
            result.put("message", "创建用户失败：" + e.getMessage());
        }

        return result;
    }

    /**
     * 用户登录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> login(UserLoginDTO dto, HttpServletRequest request) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 🔐 验证验证码（优先验证）
            if (dto.getCaptchaId() == null || dto.getCaptchaCode() == null) {
                result.put("success", false);
                result.put("message", "请输入验证码");
                return result;
            }
            
            boolean isCaptchaValid = com.kaizeli.website.controller.CaptchaController.validateCaptcha(
                dto.getCaptchaId(), 
                dto.getCaptchaCode(), 
                request.getSession()
            );
            
            if (!isCaptchaValid) {
                result.put("success", false);
                result.put("message", "验证码错误或已过期");
                return result;
            }

            // 2. 查询用户
            String sql = "SELECT id, username, password, administrator, employee_id, email, phone FROM users WHERE username = ?";
            
            Map<String, Object> user = jdbcTemplate.queryForMap(sql, dto.getUsername());
            
            if (user == null) {
                result.put("success", false);
                result.put("message", "用户不存在");
                return result;
            }

            // 3. 🔐 BCrypt验证密码
            String encryptedPassword = (String) user.get("password");
            boolean isPasswordCorrect = passwordEncoder.matches(dto.getPassword(), encryptedPassword);

            if (!isPasswordCorrect) {
                result.put("success", false);
                result.put("message", "密码错误");
                return result;
            }

            // 4. 生成JWT token（有效期3小时）
            Long userId = ((Number) user.get("id")).longValue();
            String username = (String) user.get("username");
            
            // administrator字段可能是Boolean或Integer类型
            boolean isAdmin;
            Object adminObj = user.get("administrator");
            if (adminObj instanceof Boolean) {
                isAdmin = (Boolean) adminObj;
            } else if (adminObj instanceof Number) {
                isAdmin = ((Number) adminObj).intValue() == 1;
            } else {
                isAdmin = false;
            }
            
            String token = JwtUtil.generateToken(username, isAdmin, 3 * 60 * 60 * 1000); // 3小时

            // 4. 更新token信息到数据库
            String updateSql = 
                "UPDATE users SET " +
                "current_token = ?, " +
                "token_created_at = NOW(), " +
                "token_expires_at = DATE_ADD(NOW(), INTERVAL 3 HOUR), " +
                "last_login_time = NOW(), " +
                "last_login_ip = ?, " +
                "login_count = login_count + 1, " +
                "is_token_valid = 1 " +
                "WHERE id = ?";
            
            String clientIp = getClientIP(request);
            jdbcTemplate.update(updateSql, token, clientIp, userId);

            // 5. 获取用户级别（转换为int）
            int userLevel;
            if (adminObj instanceof Number) {
                userLevel = ((Number) adminObj).intValue();
            } else if (adminObj instanceof Boolean) {
                userLevel = ((Boolean) adminObj) ? 1 : 0; // 兼容旧数据
            } else {
                userLevel = 0;
            }
            
            // 6. 返回用户信息和token
            result.put("success", true);
            result.put("message", "登录成功");
            result.put("token", token);
            result.put("userId", userId);
            result.put("username", username);
            result.put("administrator", isAdmin);
            result.put("userLevel", userLevel); // 用户级别：0=子管理员, 1=管理员, 2=总管理员
            result.put("email", user.get("email"));
            result.put("phone", user.get("phone"));
            result.put("employeeId", user.get("employee_id")); // 返回员工ID

            log.info("用户 {} 登录成功，权限级别：{}", username, userLevel);

        } catch (Exception e) {
            log.error("登录失败：{}", e.getMessage(), e);
            result.put("success", false);
            result.put("message", "登录失败：" + e.getMessage());
        }

        return result;
    }

    /**
     * 验证token
     */
    @Override
    public Map<String, Object> validateToken(String token) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 1. JWT验证
            if (!JwtUtil.validateToken(token)) {
                result.put("success", false);
                result.put("message", "Token无效");
                return result;
            }

            // 2. 数据库验证
            String sql = 
                "SELECT id, username, administrator, email, phone " +
                "FROM users " +
                "WHERE current_token = ? " +
                "AND is_token_valid = 1 " +
                "AND token_expires_at > NOW()";
            
            Map<String, Object> user = jdbcTemplate.queryForMap(sql, token);
            
            // 获取用户级别
            Object adminObj = user.get("administrator");
            int userLevel = 0;
            if (adminObj instanceof Number) {
                userLevel = ((Number) adminObj).intValue();
            }
            
            result.put("success", true);
            result.put("message", "Token有效");
            result.put("userId", user.get("id"));
            result.put("username", user.get("username"));
            result.put("administrator", userLevel >= 1); // 兼容旧逻辑
            result.put("userLevel", userLevel); // 新增用户级别
            result.put("email", user.get("email"));
            result.put("phone", user.get("phone"));

        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "Token已过期或无效");
        }

        return result;
    }

    /**
     * 登出
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> logout(String token) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 完全清除Token信息，更安全
            String sql = 
                "UPDATE users SET " +
                "is_token_valid = 0, " +
                "current_token = NULL, " +
                "token_created_at = NULL, " +
                "token_expires_at = NULL " +
                "WHERE current_token = ?";
            int rows = jdbcTemplate.update(sql, token);

            if (rows > 0) {
                result.put("success", true);
                result.put("message", "登出成功");
                log.info("用户登出成功，Token已清除");
            } else {
                result.put("success", false);
                result.put("message", "登出失败");
            }

        } catch (Exception e) {
            log.error("登出失败：{}", e.getMessage(), e);
            result.put("success", false);
            result.put("message", "登出失败：" + e.getMessage());
        }

        return result;
    }

    /**
     * 数据校验和SQL注入防护
     */
    private String validateAndSanitizeInput(UserRegisterDTO dto) {
        // 用户名校验
        if (dto.getUsername() == null || dto.getUsername().trim().isEmpty()) {
            return "用户名不能为空";
        }
        
        String username = dto.getUsername().trim();
        
        // 防止SQL注入：用户名只允许字母、数字、下划线
        if (!username.matches("^[a-zA-Z0-9_]{3,50}$")) {
            return "用户名只能包含字母、数字和下划线，长度3-50位";
        }
        
        // 防止XSS攻击：检查特殊字符
        if (containsDangerousChars(username)) {
            return "用户名包含非法字符";
        }
        
        // 密码校验
        if (dto.getPassword() == null || dto.getPassword().trim().isEmpty()) {
            return "密码不能为空";
        }
        
        if (dto.getPassword().length() < 6 || dto.getPassword().length() > 100) {
            return "密码长度必须在6-100位之间";
        }
        
        if (!dto.getPassword().equals(dto.getConfirmPassword())) {
            return "两次输入的密码不一致";
        }
        
        // 邮箱校验（如果提供）
        if (dto.getEmail() != null && !dto.getEmail().isEmpty()) {
            String email = dto.getEmail().trim();
            if (!email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")) {
                return "邮箱格式不正确";
            }
            if (containsDangerousChars(email)) {
                return "邮箱包含非法字符";
            }
        }
        
        // 手机号校验（如果提供）
        if (dto.getPhone() != null && !dto.getPhone().isEmpty()) {
            String phone = dto.getPhone().trim();
            if (!phone.matches("^1[3-9]\\d{9}$")) {
                return "手机号格式不正确";
            }
        }
        
        return null; // 校验通过
    }
    
    /**
     * 检查是否包含危险字符（防止SQL注入和XSS）
     */
    private boolean containsDangerousChars(String input) {
        if (input == null) {
            return false;
        }
        
        // 检查SQL注入常见字符
        String[] dangerousPatterns = {
            "'", "\"", ";", "--", "/*", "*/", "xp_", "sp_", 
            "exec", "execute", "select", "insert", "update", 
            "delete", "drop", "create", "alter", "union",
            "<script", "javascript:", "onerror=", "onload="
        };
        
        String lowerInput = input.toLowerCase();
        for (String pattern : dangerousPatterns) {
            if (lowerInput.contains(pattern)) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * 修改密码
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> changePassword(ChangePasswordDTO dto, String currentUsername) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 参数校验
            if (currentUsername == null || currentUsername.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "未登录或登录已过期");
                return result;
            }

            if (dto.getOldPassword() == null || dto.getOldPassword().trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "请输入旧密码");
                return result;
            }

            if (dto.getNewPassword() == null || dto.getNewPassword().trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "请输入新密码");
                return result;
            }

            if (!dto.getNewPassword().equals(dto.getConfirmPassword())) {
                result.put("success", false);
                result.put("message", "两次输入的新密码不一致");
                return result;
            }

            if (dto.getNewPassword().length() < 6 || dto.getNewPassword().length() > 100) {
                result.put("success", false);
                result.put("message", "新密码长度必须在6-100位之间");
                return result;
            }

            // 2. 查询用户当前密码
            String getUserSql = "SELECT id, password FROM users WHERE username = ?";
            Map<String, Object> user;
            try {
                user = jdbcTemplate.queryForMap(getUserSql, currentUsername);
            } catch (Exception e) {
                result.put("success", false);
                result.put("message", "用户不存在");
                return result;
            }

            // 3. 验证旧密码
            String encryptedPassword = (String) user.get("password");
            boolean isOldPasswordCorrect = passwordEncoder.matches(dto.getOldPassword(), encryptedPassword);

            if (!isOldPasswordCorrect) {
                result.put("success", false);
                result.put("message", "旧密码错误");
                return result;
            }

            // 4. 加密新密码
            String newEncryptedPassword = passwordEncoder.encode(dto.getNewPassword());

            // 5. 更新密码
            String updateSql = "UPDATE users SET password = ? WHERE username = ?";
            jdbcTemplate.update(updateSql, newEncryptedPassword, currentUsername);

            result.put("success", true);
            result.put("message", "密码修改成功");
            
            log.info("用户 {} 修改密码成功", currentUsername);

        } catch (Exception e) {
            log.error("修改密码失败：{}", e.getMessage(), e);
            result.put("success", false);
            result.put("message", "修改密码失败：" + e.getMessage());
        }

        return result;
    }

    /**
     * 获取所有在职员工列表（用于创建普通用户时选择）
     */
    @Override
    public List<Map<String, Object>> getActiveEmployees() {
        try {
            String sql = "SELECT e.id, e.employee_code, e.name, e.id_card, e.department, e.position, " +
                        "CASE WHEN u.id IS NOT NULL THEN 1 ELSE 0 END AS is_bound " +
                        "FROM employee e " +
                        "LEFT JOIN users u ON e.id = u.employee_id " +
                        "WHERE e.status = 1 AND e.id_card IS NOT NULL AND e.id_card != '' " +
                        "ORDER BY e.employee_code";
            
            List<Map<String, Object>> employees = jdbcTemplate.queryForList(sql);
            
            log.info("查询到 {} 名在职员工", employees.size());
            
            return employees;
            
        } catch (Exception e) {
            log.error("查询员工列表失败：{}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 删除用户
     * 权限说明：
     * - 总管理员(2)：可以删除管理员(1)和子管理员(0)
     * - 管理员(1)：只能删除子管理员(0)
     * - 子管理员(0)：无删除权限
     * - 不能删除自己
     * - 不能删除总管理员(2)
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> deleteUser(String targetUsername, String currentUsername) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 检查当前用户权限级别
            if (currentUsername == null || currentUsername.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "未登录或登录已过期");
                return result;
            }
            
            String checkAdminSql = "SELECT administrator FROM users WHERE username = ?";
            Integer currentUserLevel = jdbcTemplate.queryForObject(checkAdminSql, Integer.class, currentUsername);
            
            // 子管理员(0)无删除权限
            if (currentUserLevel == null || currentUserLevel == 0) {
                result.put("success", false);
                result.put("message", "权限不足：只有管理员及以上级别可以删除用户");
                log.warn("用户 {} 尝试删除用户但权限不足（级别：{}）", currentUsername, currentUserLevel);
                return result;
            }

            // 2. 检查目标用户是否存在
            if (targetUsername == null || targetUsername.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "目标用户名不能为空");
                return result;
            }
            
            // 不能删除自己
            if (targetUsername.equals(currentUsername)) {
                result.put("success", false);
                result.put("message", "不能删除自己的账号");
                log.warn("用户 {} 尝试删除自己的账号", currentUsername);
                return result;
            }

            // 检查目标用户
            String checkTargetSql = "SELECT id, username, administrator FROM users WHERE username = ?";
            Map<String, Object> targetUser;
            try {
                targetUser = jdbcTemplate.queryForMap(checkTargetSql, targetUsername);
            } catch (Exception e) {
                result.put("success", false);
                result.put("message", "目标用户不存在");
                return result;
            }

            Integer targetUserLevel = ((Number) targetUser.get("administrator")).intValue();
            
            // 3. 禁止删除总管理员
            if (targetUserLevel >= 2) {
                result.put("success", false);
                result.put("message", "禁止删除总管理员账号");
                log.warn("用户 {} 尝试删除总管理员账号，操作被拒绝", currentUsername);
                return result;
            }
            
            // 4. 权限检查：管理员(1)只能删除子管理员(0)
            if (currentUserLevel == 1 && targetUserLevel >= 1) {
                result.put("success", false);
                result.put("message", "权限不足：管理员只能删除子管理员");
                log.warn("管理员 {} 尝试删除管理员级别用户 {}，操作被拒绝", currentUsername, targetUsername);
                return result;
            }

            // 5. 执行删除
            String deleteSql = "DELETE FROM users WHERE username = ?";
            int rows = jdbcTemplate.update(deleteSql, targetUsername);

            if (rows > 0) {
                result.put("success", true);
                result.put("message", "用户删除成功");
                String targetTypeName = targetUserLevel == 1 ? "管理员" : "子管理员";
                log.info("用户删除成功：操作者={}, 被删除用户={}, 类型={}", currentUsername, targetUsername, targetTypeName);
            } else {
                result.put("success", false);
                result.put("message", "删除用户失败");
            }

        } catch (Exception e) {
            log.error("删除用户失败：{}", e.getMessage(), e);
            result.put("success", false);
            result.put("message", "删除用户失败：" + e.getMessage());
        }

        return result;
    }

    /**
     * 提升用户为总管理员
     * 权限说明：
     * - 只有总管理员(2)可以提升其他管理员(1)为总管理员(2)
     * - 只能提升管理员(1)，不能提升子管理员(0)
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> promoteToSuperAdmin(String targetUsername, String currentUsername) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 检查当前用户是否是总管理员
            if (currentUsername == null || currentUsername.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "未登录或登录已过期");
                return result;
            }
            
            String checkAdminSql = "SELECT administrator FROM users WHERE username = ?";
            Integer currentUserLevel = jdbcTemplate.queryForObject(checkAdminSql, Integer.class, currentUsername);
            
            // 只有总管理员(2)可以授权
            if (currentUserLevel == null || currentUserLevel != 2) {
                result.put("success", false);
                result.put("message", "权限不足：只有总管理员可以授予总管理员职务");
                log.warn("用户 {} 尝试授予总管理员职务但权限不足（级别：{}）", currentUsername, currentUserLevel);
                return result;
            }

            // 2. 检查目标用户是否存在
            if (targetUsername == null || targetUsername.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "目标用户名不能为空");
                return result;
            }
            
            // 不能授权给自己（自己已经是总管理员了）
            if (targetUsername.equals(currentUsername)) {
                result.put("success", false);
                result.put("message", "您已经是总管理员");
                log.warn("用户 {} 尝试授权给自己", currentUsername);
                return result;
            }

            // 检查目标用户
            String checkTargetSql = "SELECT id, username, administrator FROM users WHERE username = ?";
            Map<String, Object> targetUser;
            try {
                targetUser = jdbcTemplate.queryForMap(checkTargetSql, targetUsername);
            } catch (Exception e) {
                result.put("success", false);
                result.put("message", "目标用户不存在");
                return result;
            }

            Integer targetUserLevel = ((Number) targetUser.get("administrator")).intValue();
            
            // 3. 只能提升管理员(1)为总管理员(2)
            if (targetUserLevel == 0) {
                result.put("success", false);
                result.put("message", "只能提升管理员为总管理员，不能直接提升子管理员");
                log.warn("尝试将子管理员 {} 直接提升为总管理员，操作被拒绝", targetUsername);
                return result;
            }
            
            if (targetUserLevel >= 2) {
                result.put("success", false);
                result.put("message", "该用户已经是总管理员");
                return result;
            }

            // 4. 执行提升
            String updateSql = "UPDATE users SET administrator = 2 WHERE username = ?";
            int rows = jdbcTemplate.update(updateSql, targetUsername);

            if (rows > 0) {
                result.put("success", true);
                result.put("message", "成功将用户提升为总管理员");
                log.info("用户提升成功：操作者={}, 被提升用户={}, 新级别=总管理员(2)", currentUsername, targetUsername);
            } else {
                result.put("success", false);
                result.put("message", "提升用户失败");
            }

        } catch (Exception e) {
            log.error("提升用户失败：{}", e.getMessage(), e);
            result.put("success", false);
            result.put("message", "提升用户失败：" + e.getMessage());
        }

        return result;
    }

    /**
     * 提升子管理员为管理员
     * 权限说明：
     * - 总管理员(2)和管理员(1)都可以提升子管理员(0)为管理员(1)
     * - 只能提升子管理员(0)
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> promoteToAdmin(String targetUsername, String currentUsername) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 检查当前用户是否是管理员或总管理员
            if (currentUsername == null || currentUsername.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "未登录或登录已过期");
                return result;
            }
            
            String checkAdminSql = "SELECT administrator FROM users WHERE username = ?";
            Integer currentUserLevel = jdbcTemplate.queryForObject(checkAdminSql, Integer.class, currentUsername);
            
            // 只有管理员(1)和总管理员(2)可以提升
            if (currentUserLevel == null || currentUserLevel < 1) {
                result.put("success", false);
                result.put("message", "权限不足：只有管理员及以上级别可以提升用户");
                log.warn("用户 {} 尝试提升用户但权限不足（级别：{}）", currentUsername, currentUserLevel);
                return result;
            }

            // 2. 检查目标用户是否存在
            if (targetUsername == null || targetUsername.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "目标用户名不能为空");
                return result;
            }
            
            // 不能提升自己
            if (targetUsername.equals(currentUsername)) {
                result.put("success", false);
                result.put("message", "不能提升自己");
                log.warn("用户 {} 尝试提升自己", currentUsername);
                return result;
            }

            // 检查目标用户
            String checkTargetSql = "SELECT id, username, administrator FROM users WHERE username = ?";
            Map<String, Object> targetUser;
            try {
                targetUser = jdbcTemplate.queryForMap(checkTargetSql, targetUsername);
            } catch (Exception e) {
                result.put("success", false);
                result.put("message", "目标用户不存在");
                return result;
            }

            Integer targetUserLevel = ((Number) targetUser.get("administrator")).intValue();
            
            // 3. 只能提升子管理员(0)为管理员(1)
            if (targetUserLevel >= 1) {
                result.put("success", false);
                result.put("message", "该用户已经是管理员或总管理员");
                return result;
            }

            // 4. 执行提升
            String updateSql = "UPDATE users SET administrator = 1 WHERE username = ?";
            int rows = jdbcTemplate.update(updateSql, targetUsername);

            if (rows > 0) {
                result.put("success", true);
                result.put("message", "成功将用户提升为管理员");
                log.info("用户提升成功：操作者={}, 被提升用户={}, 新级别=管理员(1)", currentUsername, targetUsername);
            } else {
                result.put("success", false);
                result.put("message", "提升用户失败");
            }

        } catch (Exception e) {
            log.error("提升用户失败：{}", e.getMessage(), e);
            result.put("success", false);
            result.put("message", "提升用户失败：" + e.getMessage());
        }

        return result;
    }

    /**
     * 获取所有用户列表
     */
    @Override
    public List<Map<String, Object>> getAllUsers() {
        try {
            String sql = "SELECT id, username, administrator, email, phone, employee_id, login_count, last_login_time " +
                        "FROM users " +
                        "ORDER BY administrator DESC, id";
            
            List<Map<String, Object>> users = jdbcTemplate.queryForList(sql);
            
            // 为每个用户添加角色名称
            for (Map<String, Object> user : users) {
                Object adminObj = user.get("administrator");
                int level = 0;
                if (adminObj instanceof Number) {
                    level = ((Number) adminObj).intValue();
                }
                
                String roleName;
                if (level >= 2) {
                    roleName = "总管理员";
                } else if (level == 1) {
                    roleName = "管理员";
                } else {
                    roleName = "子管理员";
                }
                
                user.put("roleName", roleName);
                user.put("userLevel", level);
            }
            
            log.info("查询到 {} 个用户", users.size());
            return users;
            
        } catch (Exception e) {
            log.error("查询用户列表失败：{}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取客户端IP
     */
    private String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 防止IP注入
        if (ip != null && ip.matches("^[0-9.:a-fA-F]+$")) {
            return ip;
        }
        return "unknown";
    }
}

